using System;
using System.Collections.Generic;
using Engine.Core.Interfaces;
using Engine.Particles.Interfaces;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Engine.Particles.Effects
{
    public class ExplosionEffect : IParticleEffect
    {
        private readonly Random _random;
        private readonly List<Particle> _particles;
        private bool _effectCreated;

        public bool HasEnded
        {
            get { return _particles.Count <= 0; }
        }

        public bool Physics { get; set; }
        public Texture2D Texture { get; set; }
        public Vector2 EmitterLocation { get; set; }

        public static IParticleEffect Create(Texture2D texture, Vector2 emitterLocation, bool applyPhysics){
            return new ExplosionEffect{Texture = texture, EmitterLocation = emitterLocation, Physics = applyPhysics};
        }
        public ExplosionEffect()
        {
            _random = new Random();
            _particles = new List<Particle>();
        }
        public void Update(GameTime gameTime)
        {
            var i = 0;
            while (!_effectCreated && i < 100 )
            {
                _particles.Add(MakeParticle(100 + _random.Next(0, 150),.1f));
                _particles.Add(MakeParticle(100 + _random.Next(0, 150),.2f));
                _particles.Add(MakeParticle(100 + _random.Next(0, 150),.3f));
                i++;
            }
            _effectCreated = true;

            foreach (var particle in _particles)
            {
                particle.Update(gameTime);
                if (particle.TimeToLive < 0)
                    _particles.Remove(particle);
            }
            Cleanup();
        }

        public List<IExtendedDrawable> GetDrawables()
        {
            var list = new List<IExtendedDrawable>();
            list.AddRange(_particles);
            return list;
        }

        public List<IPhysicElement> GetPhysicObjects() {
            var list = new List<IPhysicElement>();
            list.AddRange(_particles);
            return list;
        }

        private Particle MakeParticle(int ttl = 50, float size = 1f)
        {
            var color = Color.Red;
            var timeToLive = 5000;

            var randX = (float)(_random.Next(-50, 50)*10)/100;
            var randY = (float)(_random.Next(-50, 50)*10)/100;

            var acceleration = new Vector2(randX,randY);

            return Particle.Create(Texture, EmitterLocation, color, size, timeToLive, acceleration);
        }
        private void Cleanup()
        {
            var particles = new List<Particle>();
            foreach (var particle in _particles)
            {
                if (particle.TimeToLive <= 0)
                {
                    particles.Add(particle);
                }
            }
            particles.ForEach(x => _particles.Remove(x));
        }
    }
}